package common

import (
	"bytes"
	"fmt"
	"github.com/spf13/viper"
	"math/rand"
	"os"
	"reflect"
	"strings"
	"time"
	"unicode"
)

const keyChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

// 判断文件是否存在
func IsFileExist(path string) bool {
	_, err := os.Stat(path)
	return err == nil || os.IsExist(err)
}

// 生成一个基于当前时间的特定格式的字符串
func GetTimeString() string {
	now := time.Now()
	return fmt.Sprintf("%s%d", now.Format("20060102150405"), now.UnixNano()%1e9)
}

// 产生随机字符串
func GetRandomString(length int) string {
	rand.Seed(time.Now().UnixNano())
	key := make([]byte, length)
	for i := 0; i < length; i++ {
		key[i] = keyChars[rand.Intn(len(keyChars))]
	}
	return string(key)
}

func GetOrDefault[T any](env string, defaultValue T) T {
	if viper.IsSet(env) {
		value := viper.Get(env)
		if v, ok := value.(T); ok {
			return v
		}
	}
	return defaultValue
}

// snakeCase 将字符串从驼峰命名或帕斯卡命名转换为snake_case
func SnakeCase(str string) string {
	var buf bytes.Buffer
	runes := []rune(str)
	wasUpper := false

	for i, r := range runes {
		if unicode.IsUpper(r) {
			if i > 0 && !wasUpper {
				buf.WriteRune('_')
			}
			buf.WriteRune(unicode.ToLower(r))
			wasUpper = true
		} else {
			buf.WriteRune(r)
			wasUpper = false
		}
	}

	return strings.ToLower(buf.String())
}

// 通过反射 获取必要的 数据
func GetReflectColumnData(data interface{}) map[string]interface{} {
	resultMap := make(map[string]interface{})

	val := reflect.ValueOf(data)
	if val.Kind() == reflect.Ptr {
		val = val.Elem()
	}
	typ := val.Type()
	for i := 0; i < val.NumField(); i++ {
		field := typ.Field(i)
		valueField := val.Field(i)
		value := valueField.Interface()
		if valueField.Kind() != reflect.Ptr && value != "" {
			resultMap[field.Name] = value
		}
	}
	return resultMap
}
